<?php

namespace Sharks\Core\Make;

use Sharks\Core\AppContext;
use Sharks\Core\Cfg\AppConfig;
use Sharks\Core\Module;
use Sharks\Core\Support\Log\Log;
use Sharks\Core\Support\Storage\ArrayLoader;
use Sharks\Core\Support\Storage\StorageArrayUtils;

/**
 * 各模块初始化
 * 依赖：
 *      AppConfigMaker
 */
class ModuleMaker extends Maker {

    public function dev(AppContext $app) {
        $this->make($app);
    }

    public function server(AppContext $app) {
        $this->make($app);
    }

    protected function make(AppContext $app) {

        // 初始化各模块
        foreach (AppConfig::get('dependencies', array()) as $dependency) {
            $this->loadModule($app, $dependency);
        }

        // 初始化应用模块
        $appClass = "\\Source\\Loader";
        if (class_exists($appClass)) {
            $makerLoader = new $appClass;
            $makerLoader->load($app);// 不把app当成module加载
        }

        $moduleSituation = StorageArrayUtils::read('module.php', array());
        if (empty($moduleSituation)) {
            $moduleSituation = array();
            foreach (Module::all() as $module) {
                $module->loader()->up($app);
                $moduleSituation[$module->name()] = 'up';
            }
            StorageArrayUtils::write('module.php', $moduleSituation);
        }
    }

    protected function loadModule(AppContext $app, $moduleName, array &$loaded = array()) {

        if (!in_array($moduleName, $loaded)) {
            $class = "\\Sharks\\Module\\$moduleName\\Loader";

            if (class_exists($class)) {
                $maker = new $class;
                $module = $maker->load($app);
                foreach ($module->cfg()->get('dependencies', array()) as $dependency) {
                    $this->loadModule($app, $dependency, $loaded);
                }

                Module::add($module);
                array_push($loaded, $moduleName);
            }
            else {
                Log::warning("$moduleName 不能加载，请检查composer.json");
            }
        }
    }

    /**
     * 前置依赖
     */
    public function makers() {
        return array(AppConfigMaker::class);
    }
}